package c2.cross.server.controller;

import c2.advanced.business.demo.po.DemoBook;
import c2.advanced.business.demo.po.DemoCat;
import com.mongodb.client.result.DeleteResult;
import easy.java.spring.annotation.MyGetMapping;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.ExecutableRemoveOperation;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static c2.advanced.server.controller.ControllerTool.R;

@Slf4j
@RequestMapping("/demo/mongo/")
@Controller
public class DemoMongoController extends CrossBaseController {

    @Resource
    MongoTemplate mongoTemplate;



    // http://localhost:8585/demo/mongo/addBooks
    @MyGetMapping("addBooks")
    @ResponseBody
    public Object addBooks() {
        return R(() -> {
            DemoBook b1 = mongoTemplate.save(DemoBook.create(3, "《第三本》", "en","2020-12-13 12:31:15", null));
            DemoBook b2 = mongoTemplate.save(DemoBook.create(6, "《第六本》", "en","2021-01-08 03:04:05", 3.1415));
            DemoBook b3 = mongoTemplate.save(DemoBook.create(9, "《第九本》", "zh","2021-01-08 03:04:05", new Date()));
            return new DemoBook[] { b1, b2, b3 };
        });
    }

    // http://localhost:8585/demo/mongo/addCats
    @MyGetMapping("addCats")
    @ResponseBody
    public Object addCats() {
        return R(() -> {
            DemoCat c1 = mongoTemplate.save(DemoCat.create("九命", 9l), DemoCat.COLLECTION);
            DemoCat c2 = mongoTemplate.save(DemoCat.create("短命", 1l), DemoCat.COLLECTION);
            DemoCat c3 = mongoTemplate.save(DemoCat.create("无命", null), DemoCat.COLLECTION);
            return new DemoCat[] { c1, c2, c3 };
        });
    }

    // http://localhost:8585/demo/mongo/findAllBooks
    @MyGetMapping("findAllBooks")
    @ResponseBody
    public Object findAllBooks() {
        return R(()->mongoTemplate.findAll(DemoBook.class));
    }

    // http://localhost:8585/demo/mongo/findAllCats
    @MyGetMapping("findAllCats")
    @ResponseBody
    public Object findAllCats() {
        return R(()->mongoTemplate.findAll(DemoCat.class, DemoCat.COLLECTION));
    }

    // http://localhost:8686/demo/mongo/getBook?id=3
    @MyGetMapping("getBook")
    @ResponseBody
    public Object getBook(@RequestParam Integer id) {
        return R(()->{
            DemoBook book = mongoTemplate.findById(id, DemoBook.class, DemoBook.COLLECTION);
            return book;
        });
    }

    // http://localhost:8585/demo/mongo/queryBooks
    @MyGetMapping("queryBooks")
    @ResponseBody
    public Object queryBooks() {
        return R(()->{
            Query query = Query.query(Criteria.where("type").is("en"));
            List<DemoBook> books = mongoTemplate.find(query, DemoBook.class);
            return books;
        });
    }

    // http://localhost:8585/demo/mongo/queryCats
    @MyGetMapping("queryCats")
    @ResponseBody
    public Object queryCats() {
        return R(()->{
            Query query = Query.query(Criteria.where("age").gte(1L));
            List<DemoCat> cats = mongoTemplate.find(query, DemoCat.class, DemoCat.COLLECTION);
            return cats;
        });
    }

    // http://localhost:8585/demo/mongo/deleteAllBooks
    @MyGetMapping("deleteAllBooks")
    @ResponseBody
    public Object deleteAllBooks() {
        return R(()->{
            ExecutableRemoveOperation.ExecutableRemove<DemoBook> rm = mongoTemplate.remove(DemoBook.class);
            Map<String, Object> map = new HashMap<>();
            map.put("DeletedCount", rm.all().getDeletedCount());
            map.put("wasAcknowledged", rm.all().wasAcknowledged());
            return map;
        });
    }

    // http://localhost:8585/demo/mongo/deleteAllCats
    @MyGetMapping("deleteAllCats")
    @ResponseBody
    public Object deleteAllCats() {
        return R(()->{
            DeleteResult dr = mongoTemplate.remove(new Query(), DemoCat.COLLECTION);
            Map<String, Object> map = new HashMap<>();
            map.put("DeletedCount", dr.getDeletedCount());
            map.put("wasAcknowledged", dr.wasAcknowledged());
            return map;
        });
    }

    // http://localhost:8585/demo/mongo/dropBookCollection
    @MyGetMapping("dropBookCollection")
    @ResponseBody
    public Object dropBookCollection() {
        return R(()->{
            mongoTemplate.dropCollection(DemoBook.class);
            return "已丢弃book collection";
        });
    }

    // http://localhost:8585/demo/mongo/dropCatCollection
    @MyGetMapping("dropCatCollection")
    @ResponseBody
    public Object dropCatCollection() {
        return R(()->{
            mongoTemplate.dropCollection(DemoCat.COLLECTION);
            return "已丢弃cat collection";
        });
    }

}
